<template>
  <div>
    <vxe-modal
      :title="modalTitle"
      v-model="show"
      :loading="loading"
      :mask="true"
      :lock-view="true"
      width="60vw"
      height="60vh"
      destroy-on-close
      show-zoom
      remember
      resize
      show-footer
    >
      <!-- 主体部分： form 表单 -->
      <el-form
        ref="refForm"
        :model="formData"
        :rules="formRules"
        label-width="120px"
        @submit.prevent
      >
        <el-tabs v-model="activeTab">
          <!-- 第一选项卡 -->
          <el-tab-pane
            :label="$t('menu.dev.menu.tabs.base', '基本信息')"
            name="basic"
          >
            <!-- 基本信息 -->
            <div class="form-section">
              <el-row :gutter="20">
                <el-col :xs="24" :sm="12" :md="12">
                  <el-form-item-plus
                    :label="$t('menu.dev.menu.field.type', '类型')"
                    prop="type"
                    :tooltipContent="
                      $t(
                        'menu.dev.menu.tip.type',
                        '系统菜单分为目录、菜单、外链和IFRAME四种类型（API仅目录和菜单）',
                      )
                    "
                  >
                    <el-radio-group
                      v-model="formData.type"
                      :disabled="isEditMode"
                    >
                      <el-radio :value="MenuTypeEnum.MENU"> 菜单 </el-radio>
                      <el-radio :value="MenuTypeEnum.CATALOG"> 目录 </el-radio>
                    </el-radio-group>
                  </el-form-item-plus>
                </el-col>
                <el-col :xs="24" :sm="12" :md="12">
                  <el-form-item-plus
                    :label="$t('menu.dev.menu.field.pid', '父菜单')"
                    prop="pid"
                    :tooltipContent="
                      $t(
                        'menu.dev.menu.tip.pid',
                        '菜单必须具有父目录或者父菜单',
                      )
                    "
                  >
                    <ra-dict-tree-select
                      v-model="formData.pid"
                      code="sys_api_tree_options"
                      type="tree-select"
                      :default-expanded-keys="[0]"
                      check-strictly
                    ></ra-dict-tree-select>
                  </el-form-item-plus>
                </el-col>
                <el-col :xs="24" :sm="12" :md="12">
                  <el-form-item-plus
                    :label="$t('menu.dev.menu.field.name', '名称')"
                    prop="name"
                    :tooltipContent="
                      $t(
                        'menu.dev.menu.tip.name',
                        '菜单名称是用于显示在菜单栏上面的名称；如果采用多语言则此处仅定义键名。',
                      )
                    "
                  >
                    <el-input
                      v-model="formData.name"
                      :placeholder="$p('menu.dev.menu.field.name', '菜单名称')"
                      maxlength="50"
                      show-word-limit
                    />
                  </el-form-item-plus>
                </el-col>
                <el-col :xs="24" :sm="12" :md="12">
                  <el-form-item-plus
                    :label="$t('menu.dev.menu.field.controller', '控制器')"
                    prop="controller"
                    :tooltipContent="
                      $t(
                        'menu.dev.menu.tip.controller',
                        '请输入后端为前端提供数据的控制器类的完整名称',
                      )
                    "
                  >
                    <el-input
                      v-model="formData.controller"
                      placeholder="System/User"
                    />
                  </el-form-item-plus>
                </el-col>

                <el-col :xs="24" :sm="12" :md="12">
                  <el-form-item-plus
                    :label="$t('common.field.sort', '排序')"
                    :tooltipContent="
                      $t(
                        'menu.dev.menu.tip.sort',
                        '默认可以留空，系统会自动设置排序号',
                      )
                    "
                    prop="sort"
                  >
                    <el-input-number
                      v-model="formData.sort"
                      controls-position="right"
                      :min="0"
                    />
                  </el-form-item-plus>
                </el-col>

                <el-col :xs="24" :sm="12" :md="12">
                  <el-form-item-plus
                    prop="status"
                    :label="$t('common.field.status', '状态')"
                    :tooltipContent="
                      $t(
                        'menu.dev.menu.tip.status',
                        '设置菜单状态，禁用则不可用',
                      )
                    "
                  >
                    <ra-dict-select
                      v-model="formData.status"
                      code="status_options"
                      type="radio"
                    />
                  </el-form-item-plus>
                </el-col>
              </el-row>
            </div>

            <!-- 菜单 -->
            <div shadow="always" class="form-section" v-if="isMenuType">
              <el-row :gutter="20">
                <el-col :xs="24" :sm="12" :md="12">
                  <el-form-item-plus
                    prop="gen_table"
                    :label="$t('menu.dev.menu.field.gen_table', '创建表')"
                    :tooltipContent="
                      $t('menu.dev.menu.tip.gen_table', '是否自动创建数据库表')
                    "
                  >
                    <ra-dict-select
                      v-model="formData.gen_table"
                      code="yes_or_not_options"
                      type="radio"
                    />
                  </el-form-item-plus>
                </el-col>
                <el-col :xs="24" :sm="12" :md="12">
                  <el-form-item-plus
                    :label="$t('menu.dev.menu.field.connect', '连接')"
                    prop="connect"
                    :tooltipContent="
                      $t(
                        'menu.dev.menu.tip.connect',
                        '第一个下拉框用于选择数据库连接，如无跨数据库操作，选择默认即可',
                      )
                    "
                  >
                    <el-select style="width: 130px" v-model="formData.connect">
                      <el-option
                        v-for="item in connectOptions"
                        :key="item.value"
                        :label="item.label"
                        :value="item.value"
                      />
                    </el-select>
                  </el-form-item-plus>
                </el-col>
                <el-col :xs="24" :sm="12" :md="12">
                  <el-form-item-plus
                    :label="$t('menu.dev.menu.field.table_name', '表名')"
                    prop="table_name"
                  >
                    <el-input
                      style="width: 100%"
                      v-model="formData.table_name"
                      :placeholder="$p('menu.dev.menu.field.table_name')"
                    >
                    </el-input>
                  </el-form-item-plus>
                </el-col>
                <el-col :xs="24" :sm="12" :md="12">
                  <el-form-item-plus
                    :label="$t('menu.dev.menu.field.primary_key', '主键列')"
                    prop="primary_key"
                    :tooltipContent="
                      $t(
                        'menu.dev.menu.tip.primary_key',
                        '请输入此表的主键字段名，默认为id',
                      )
                    "
                  >
                    <el-input
                      v-model="formData.primary_key"
                      :placeholder="
                        $p('menu.dev.menu.field.primary_key', '主键字段名')
                      "
                    >
                    </el-input>
                  </el-form-item-plus>
                </el-col>
              </el-row>
            </div>
          </el-tab-pane>

          <!-- 第二个选项卡 -->
          <el-tab-pane
            :label="$t('menu.dev.menu.tabs.extend', '扩展信息')"
            name="extend"
          >
            <div shadow="always" class="form-section">
              <el-row :gutter="20">
                <el-col :xs="24" :sm="24" :md="24">
                  <el-form-item-plus
                    :label="$t('menu.dev.menu.field.config', '高级配置')"
                    prop="config"
                    label-position="top"
                  >
                    <ra-object-editor v-model="formData.config" />
                    <!-- <ra-array-editor v-model="formData.config" /> -->
                  </el-form-item-plus>
                </el-col>
              </el-row>
            </div>
          </el-tab-pane>
        </el-tabs>
      </el-form>

      <!-- footer -->
      <template #footer>
        <div>
          <el-button type="info" @click="cancelHandler">
            {{ $t('common.action.cancel', '取消') }}
          </el-button>
          <el-button type="warning" @click="resetHandler">
            {{ $t('common.action.reset', '重置') }}
          </el-button>
          <el-button type="primary" @click="submitHandler" :loading="loading">
            {{ $t('common.action.confirm', '确定') }}
          </el-button>
        </div>
      </template>
    </vxe-modal>
  </div>
</template>

<script setup>
// 设置选项式 API 的内容
defineOptions({
  // 组件名称
  name: 'AdminApiForm',
  // 阻止透传非 props 属性
  inheritAttrs: false,
});

import { useDictStore } from '@/store';
import { smartTranslate as $t, transPlaceholder as $p } from '@/lang';
import { ElMessage } from 'element-plus';
import { MenuTypeEnum } from '@/enums';
import {
  FORM_MODE,
  DEFAULT_CONNECT,
  VALIDATION_ERROR_NAME,
} from './composables/constants';
import ApiAPI from '@/api/admin/dev/api';
import LangAPI from '@/api/admin/admin/i18n';
import { useFormValidation } from './composables/useFormValidation';
import { useMenuFormData } from './composables/useFormData';
import { generateMenuDetails } from './composables/utils';
import { watch } from 'vue';

// Props定义
const props = defineProps({
  mode: {
    type: String,
    default: FORM_MODE.ADD,
    validator: (value) => Object.values(FORM_MODE).includes(value),
  },
});

// 字典
const dictStore = useDictStore();
// 表单验证
const { validateForm, clearValidation } = useFormValidation();
// 表单数据管理
const { formData, initialFormData, resetFormData, initFormData } =
  useMenuFormData();

// 表单数据是否载入完成
const isLoaded = ref(false);
// 定义可触发事件
const emit = defineEmits(['reload']);
// 是否显示载入效果
const loading = ref(false);
// 翻译加载状态
const translationLoading = ref(false);
// 是否显示
const show = ref(false);
// 选项卡
const activeTab = ref('basic');
// 表单对象
const refForm = ref(null);
// 数据库连接
const connectOptions = ref([]);
// 多语言列表
const languageList = ref([]);

// 计算属性：模态框标题
const modalTitle = computed(() => {
  return props.mode === FORM_MODE.ADD
    ? $t('common.action.add', '新增')
    : $t('common.action.update', '修改');
});

// 计算属性：是否为编辑模式
const isEditMode = computed(() => props.mode === FORM_MODE.EDIT);

// 计算属性：菜单类型判断
const isMenuType = computed(() => formData.value.type === MenuTypeEnum.MENU);
// const isCatalogType = computed(
//   () => formData.value.type === MenuTypeEnum.CATALOG,
// );
// const isIframeType = computed(
//   () => formData.value.type === MenuTypeEnum.IFRAME,
// );
// const isExtlinkType = computed(
//   () => formData.value.type === MenuTypeEnum.EXTLINK,
// );

// 表单验证规则
const formRules = reactive({
  pid: [
    {
      required: true,
      message: $p('menu.dev.menu.field.pid', '父菜单'),
      trigger: 'blur',
    },
  ],
  name: [
    {
      required: true,
      message: $p('menu.dev.menu.field.name', '菜单名称'),
      trigger: 'blur',
    },
    {
      max: 50,
      message: $t(
        'common.message.validate.max',
        '{field}不能超过{max}个字符！',
        {
          field: $t('menu.dev.menu.field.name'),
          max: 50,
        },
      ),
      trigger: 'blur',
    },
  ],
  controller: [
    {
      required: true,
      message: $p('menu.dev.menu.field.controller', '控制器名称'),
      trigger: 'blur',
    },
  ],
  connect: [
    {
      trigger: 'blur',
      validator: (_, value, callback) => {
        if (formData.value?.gen_table === 1 && !value) {
          callback(new Error($p('menu.dev.menu.field.connect', '连接')));
        } else {
          callback();
        }
      },
    },
  ],
  table_name: [
    {
      trigger: 'blur',
      validator: (_, value, callback) => {
        if (formData.value?.gen_table === 1 && !value) {
          callback(new Error($p('menu.dev.menu.field.table_name', '表名')));
        } else {
          callback();
        }
      },
    },
  ],
});

/**
 * 方法
 */

// 重置表单
const resetForm = () => {
  if (refForm.value) {
    refForm.value.resetFields();
  }
  resetFormData();
};

// 获取翻译数据
const getTransData = async () => {
  if (!formData.value.key) {
    ElMessage.error($P('menu.dev.menu.field.lang_key', '键名'));
    return;
  }

  try {
    translationLoading.value = true;
    const { data } = await LangAPI.getTransData({ key: formData.value.key });
    formData.value.translations = data;
    ElMessage.success(
      $t('common.message.success.general', '{action}成功！', {
        action: $t('common.action.load', '加载'),
      }),
    );
  } catch (error) {
    console.error('Error loading translation data:', error);
  } finally {
    translationLoading.value = false;
  }
};

// 加载基础数据
const loadBaseData = async () => {
  try {
    const [connects, languages] = await Promise.all([
      ApiAPI.getConnects(),
      LangAPI.getLangList(),
    ]);
    connectOptions.value = connects.data;
    languageList.value = languages.data.languages;
  } catch (error) {
    console.error('Error loading base data:', error);
    ElMessage.error($t('common.message.info.load_failed', '加载失败！'));
  }
};

// 滚动到第一个验证错误的字段
const scrollToFirstError = () => {
  nextTick(() => {
    const firstErrorField = document.querySelector(
      'div.is-error .el-form-item__content',
    );
    if (firstErrorField) {
      firstErrorField.scrollIntoView({
        behavior: 'smooth',
        block: 'center',
      });
    }
  });
};
// 处理语言键更新
const handleKeyUpdate = (newKey) => {
  formData.value.key = newKey;
};

/**
 * 操作句柄
 */
// 提交操作（统一处理新增和编辑）
const submitHandler = async () => {
  try {
    await validateForm(refForm.value); // 使用封装的验证函数
    loading.value = true;

    const postData = { ...formData.value };
    console.log('Form Data :', postData);

    if (props.mode === FORM_MODE.ADD) {
      await ApiAPI.add(postData);
      ElMessage.success(
        $t('common.message.success.general', '{action}成功！', {
          action: $t('common.action.add', '新增'),
        }),
      );
    } else {
      await ApiAPI.update(postData);
      ElMessage.success(
        $t('common.message.success.general', '{action}成功！', {
          action: $t('common.action.update', '修改'),
        }),
      );
    }

    // 重新加载字典
    dictStore.refreshDictionaryCache();

    resetForm();
    show.value = false;
    emit('reload');
  } catch (error) {
    console.error(`Error in ${props.mode}Handler:`, error);

    // 如果是验证错误，滚动到第一个错误字段
    if (error.name === VALIDATION_ERROR_NAME) {
      scrollToFirstError();
      return;
    }

    // 处理API错误
    const errorMessage =
      error.response?.data?.message ||
      (props.mode === FORM_MODE.ADD
        ? $t('common.message.failed.general', '{action}失败！', {
            action: $t('common.action.add', '新增'),
          })
        : $t('common.message.failed.general', '{action}失败！', {
            action: $t('common.action.update', '修改'),
          }));

    ElMessage.error(errorMessage);
  } finally {
    loading.value = false;
  }
};

// 取消操作
const cancelHandler = () => {
  resetForm();
  show.value = false;
};

// 重置表单操作
const resetHandler = () => {
  resetForm();
};

watch(
  () => formData.value.controller,
  (newController) => {
    if (newController && props.mode === FORM_MODE.ADD) {
      const details = generateMenuDetails(newController);
      Object.assign(formData.value, {
        table_name: details.table_name,
        key: details.langKey,
      });
    }
  },
);

// 监听
watch(
  () => formData.value.type,
  (newValue) => {
    if (newValue === MenuTypeEnum.MENU) {
      formData.value.gen_table = 1;
      formData.value.gen_code = 1;
    }
    if (newValue === MenuTypeEnum.CATALOG) {
      formData.value.gen_table = 0;
      formData.value.gen_code = 0;
    }
  },
);
/**
 * 暴露方法
 */
defineExpose({
  async show(id) {
    // 操作类型
    if (props.mode === FORM_MODE.ADD) {
      // console.log('显示添加对话框，所属菜单ID:', id);
      // 设置所属字典
      if (id) {
        formData.value.menu_id = id;
      }
      // 加载基础数据
      loadBaseData();
      // 初始化表单数据
      initFormData();
      // 显示组件
      show.value = true;
      // 重置表单
      nextTick(() => {
        resetForm();
        isLoaded.value = true;
      });
    } else {
      // 编辑模式：加载数据
      // console.log('显示编辑对话框，ID:', id);
      const params = { id };
      loading.value = true;

      try {
        const { data } = await ApiAPI.getFormData(params);
        // 加载基础数据
        loadBaseData();
        // 初始化表单数据
        initFormData(data);
        // 显示组件
        show.value = true;
        nextTick(() => {
          // 重置表单验证状态
          clearValidation(refForm.value); // 使用封装的清除验证函数
          // 数据是否载入完成
          isLoaded.value = true;
        });
      } catch (error) {
        console.error('Error loading form data:', error);
        ElMessage.error($t('common.message.info.load_failed', '加载失败！'));
      } finally {
        loading.value = false;
      }
    }
  },
});
</script>

<style lang="scss" scoped>
.form-section {
  margin: 5px;
  border: 1px solid #dcdfe6;
  padding: 5px;
  border-radius: 4px;
}
</style>
